﻿//---------------------------------------------------------------------
//  Copyright (c) 2012-2013 Daun Project.  All rights reserved.
//  http://daun.codeplex.com
//  http://www.daun-project.com
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

using Daun.Cores;
using Daun.Controls.TreeGridView;
using Daun.Controls;
using Daun.Cores.Entities;
namespace Daun.Forms
{
    public partial class MainForm : Form
    {
        private Dictionary<string, MongoEngine> _servers = new Dictionary<string, MongoEngine>();
        private List<string> _pageList = new List<string>();
        private TreeNode _rootNode = null;
        public MainForm()
        {
            InitializeComponent();
            //Test();
        }

        #region MongoDB server Processing

        private void InitialTree()
        {
            _rootNode = new TreeNode();
            _rootNode.Text = "MongoDB Servers";
            _rootNode.ImageIndex = 0;
            _rootNode.SelectedImageIndex = 0;
            _rootNode.Tag = "--";

            treeMain.Nodes.Add(_rootNode);
        }
        private void Test()
        {

            TabPage page = new TabPage();
            DocumentUserControl uc = new DocumentUserControl();
            uc.Populate();
            page.Controls.Add(uc);
            tabControlMain.TabPages.Add(page);

            
        }
        private void PopulateMongoServer(string id, string serverName)
        {
            if (_rootNode == null)
                InitialTree();

            TreeNode node = _rootNode.Nodes.Add(id, serverName);
            node.ImageIndex = 1;
            node.SelectedImageIndex = 1;
            node.Tag = 1;            

            List<string> dbs = _servers[id].GetDatabaseList();

            foreach (var db in dbs)
            {
                TreeNode node1 = node.Nodes.Add(db, db);
                node1.ImageIndex = 2;
                node1.SelectedImageIndex = 2;
                node1.Tag = 2;

                TreeNode node11 = node1.Nodes.Add("Collections", "Collections");
                node11.ImageIndex = 3;
                node11.SelectedImageIndex = 3;
                node11.Tag = 3;

                PopulateCollection(id, db, node11);
                
                TreeNode node12 = node1.Nodes.Add("Users", "Users");
                node12.Name = string.Format("{0}/{1}", id, db);
                node12.ImageIndex = 5;
                node12.SelectedImageIndex = 5;
                node12.Tag = 4;

                PopulateUsers(id, db, node12);
            }            

            //treeMain.ExpandAll();
        }

        private void PopulateCollection(string id,string db,TreeNode rootCollection)
        {
            rootCollection.Nodes.Clear();
            List<string> docs = _servers[id].GetCollectionList(db);
            foreach (var doc in docs)
            {
                TreeNode node = rootCollection.Nodes.Add(
                    string.Format("{0}/{1}/{2}", id, db, doc),
                    doc);
                node.ImageIndex = 4;
                node.SelectedImageIndex = 4;
                node.Tag = 5;
            }
        }
        private void PopulateUsers(string id, string db, TreeNode rootCollection)
        {
            rootCollection.Nodes.Clear();
            List<string> users = _servers[id].GetUserList(db);
            foreach (var user in users)
            {
                TreeNode node = rootCollection.Nodes.Add(
                    string.Format("{0}/{1}/{2}", id, db, user),
                    user);
                node.ImageIndex = 6;
                node.SelectedImageIndex = 6;
                node.Tag = 6;
            }
        }
        #endregion

        private void tabControlMain_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
              tabControlMain.ContextMenuStrip = contextMenuStripTab;
            }
        }

        private void tabControlMain_MouseUp(object sender, MouseEventArgs e)
        {
            tabControlMain.ContextMenuStrip = null;
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // connect to mongodb server
            ConnectForm frm = new ConnectForm();
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (!_servers.ContainsKey(frm.DBEngine.EngineId.ToString()))
                {
                    _servers.Add(frm.DBEngine.EngineId.ToString(), frm.DBEngine);
                    PopulateMongoServer(frm.DBEngine.EngineId.ToString(),frm.DBEngine.UniqueName.ToLower());
                }
            }
        }

        private void treeMain_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeViewHitTestInfo hit = treeMain.HitTest(e.X, e.Y);
                if (hit != null)
                {
                    if (hit.Node != null)
                    {
                        treeMain.SelectedNode = hit.Node;
                        int selectedTag = (int)hit.Node.Tag;
                        switch (selectedTag)
                        {
                            case 1:
                                contextMenuHost.Show(treeMain, e.Location);
                                break;
                            case 4:
                                viewToolStripMenuItem.Visible = true;
                                deleteToolStripMenuItem.Visible = false;
                                contextMenuUser.Show(treeMain, e.Location);
                                break;
                            case 5:
                                contextMenuColls.Show(treeMain, e.Location);
                                break;
                            case 6:
                                viewToolStripMenuItem.Visible = false;
                                deleteToolStripMenuItem.Visible = true;
                                contextMenuUser.Show(treeMain, e.Location);
                                break;
                            default:
                                break;
                        }
                       
                    }
                }
            }
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // disconnect mongodb engine
            TreeNode selected = treeMain.SelectedNode;
            string[] items = selected.Name.Split(new char[] { '/' });
            _servers[items[0]].Disconnect();
            _servers.Remove(items[0]);
            treeMain.Nodes.Remove(selected);

            // remove tab relates to closed server
            List<string> removes = new List<string>();            
            for (int i = 0; i < tabControlMain.TabPages.Count;i++ )
            {
                if (tabControlMain.TabPages[i].Name.IndexOf(items[0]) >= 0)
                    removes.Add(tabControlMain.TabPages[i].Name);               
            }
            foreach (var remove in removes)
                tabControlMain.TabPages.RemoveByKey(remove);
        }

        private void openAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // view document
            TreeNode selected = treeMain.SelectedNode;
            if (!_pageList.Contains(selected.Name))
            {
                string[] items = selected.Name.Split(new char[] { '/' });

                TabPage page = new TabPage(selected.Name);                
                page.Name = selected.Name;
                int index = selected.Name.IndexOf('/');
                page.Text = string.Format("{0}/{1}", _servers[items[0]].ServerName, selected.Name.Substring(index+1));
                DocumentUserControl uc = new DocumentUserControl();
                uc.DBEngine = _servers[items[0]];
                uc.CollectionName = items[2];
                uc.DatabaseName = items[1];
                uc.Dock = DockStyle.Fill;
                uc.Populate();
                page.Controls.Add(uc);
                page.Tag = items[0];
                tabControlMain.TabPages.Add(page);
                _pageList.Add(selected.Name);
            }
            else
            {
                if (tabControlMain.TabPages[selected.Name] != null)
                {
                    tabControlMain.SelectedTab = tabControlMain.TabPages[selected.Name];
                    ((DocumentUserControl)tabControlMain.SelectedTab.Controls[0]).RefreshData();
                }
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // new document
            TreeNode selected = treeMain.SelectedNode;
            string[] items = selected.Name.Split(new char[] { '/' });

            DocumentForm frm = new DocumentForm();
            frm.Mode = FormMode.New;
            frm.DBEngine = _servers[items[0]];
            frm.CollectionName = items[2];
            frm.DatabaseName = items[1];
            frm.Text = String.Format("Add New Document ({0})", selected.Name);
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                DocumentProperty doc = frm.SelectedObject;
                List<Document> newDoc = doc.GetDocuments();
                _servers[items[0]].InsertNewDocument(items[1],items[2],newDoc);

                if (tabControlMain.TabPages[selected.Name] != null)
                {
                    tabControlMain.SelectedTab = tabControlMain.TabPages[selected.Name];
                    ((DocumentUserControl)tabControlMain.SelectedTab.Controls[0]).RefreshData();
                }
            }
        }
        private void dropToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //delete collection
            DialogResult dlg = MessageBox.Show("Are you sure to delete the selected collection?",
                                    "Confirmation",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question);
            if (dlg == DialogResult.Yes)
            {
                TreeNode selected = treeMain.SelectedNode;
                TreeNode parent = selected.Parent;
                string name = selected.Name;
                string[] items = name.Split(new char[] { '/' });
                _servers[items[0]].DeleteCollection(items[1], items[2]);

                PopulateCollection(items[0], items[1], parent);
                if (_pageList.Contains(name))
                {
                    TabPage tab = tabControlMain.TabPages[name];
                    _pageList.Remove(selected.Name);
                    if (tab!=null)
                        tabControlMain.TabPages.Remove(tab);
                }
            }
        }
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dlg = MessageBox.Show("Are you sure to exit?",
                                    "Confirmation",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question);

            if (dlg == DialogResult.Yes)
            {
                if (_servers.Keys.Count > 0)
                {
                    foreach (KeyValuePair<string, MongoEngine> item in _servers)
                    {
                        if (item.Value != null)
                            item.Value.Disconnect();
                    }
                    _servers.Clear();
                }
            }
            else
                e.Cancel = true;
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void toolStripButtonConnect_Click(object sender, EventArgs e)
        {
            connectToolStripMenuItem_Click(sender, e);
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // close a tab
            TabPage selected = tabControlMain.SelectedTab;
            _pageList.Remove(selected.Name);
            tabControlMain.TabPages.Remove(selected);
        }

        private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // close all tabs
            tabControlMain.TabPages.Clear();
            _pageList.Clear();
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // refresh content
            TabPage selected = tabControlMain.SelectedTab;
            DocumentUserControl uc = (DocumentUserControl)selected.Controls[0];
            uc.RefreshData();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutUs frm = new AboutUs();
            frm.ShowDialog();
        }

        private void toolStripButtonRefreshTree_Click(object sender, EventArgs e)
        {
            //refresh
        }

        private void renameCollectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // rename collection
            TreeNode selected = treeMain.SelectedNode;
            RenameCollectionForm frm = new RenameCollectionForm();
            frm.OldCollectionName = selected.Text;
            DialogResult dlg = frm.ShowDialog();
            if (dlg == DialogResult.OK)
            {                
                TreeNode parent = selected.Parent;
                string[] items = selected.Name.Split(new char[] { '/' });
                _servers[items[0]].RenameCollection(items[1], items[2],frm.NewCollectionName);

                PopulateCollection(items[0], items[1], parent);
                if (_pageList.Contains(selected.Name))
                {
                    TabPage tab = tabControlMain.TabPages[selected.Name];
                    _pageList.Remove(selected.Name);
                    if (tab != null)
                        tabControlMain.TabPages.Remove(tab);
                }
            }
        }

        private void howToUseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process process = new Process();
            ProcessStartInfo info = new ProcessStartInfo("http://www.daun-project.com");
            process.StartInfo = info;
            process.Start();
        }

        private void viewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // add new user
            TreeNode selected = treeMain.SelectedNode;
            UserForm frm = new UserForm();            
            DialogResult dlg = frm.ShowDialog();
            if (dlg == DialogResult.OK)
            {
                 string[] items = selected.Name.Split(new char[] { '/' });
                _servers[items[0]].InsertNewUser(items[1], frm.UserName,frm.Password,frm.IsReadOnlyUser);

                PopulateUsers(items[0], items[1], selected);
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //delete user
            DialogResult dlg = MessageBox.Show("Are you sure to delete the selected user?",
                                    "Confirmation",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question);
            if (dlg == DialogResult.Yes)
            {
                TreeNode selected = treeMain.SelectedNode;
                TreeNode parent = selected.Parent;
                string[] items = selected.Name.Split(new char[] { '/' });
                _servers[items[0]].DeleteUser(items[1], selected.Text);

                PopulateUsers(items[0], items[1], parent);
            }
            
        }

        
    }
}
